package zhongbo.java.air.listener;

import cn.hutool.json.JSONNull;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import zhongbo.java.air.Dto.FlightPathDto;
import zhongbo.java.air.common.exception.BusinessException;
import zhongbo.java.air.common.util.JsonUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;


@Component
@Slf4j
public class RedisSubscribeLogChanelListener implements MessageListener {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RedisLogChanelPublisher redisLogChanelPublisher;

    /**
     * 接受广播消息
     *
     * @param message
     * @param bytes
     */
    @Override
    public void onMessage(Message message, byte[] bytes) {
        String msg = redisTemplate.getStringSerializer().deserialize(message.getBody());

        log.info("广播消息内容：{}", msg);

        String json = convert(msg);
        System.out.println("发送的消息" + json);

        redisLogChanelPublisher.broadcast(json);
    }

    private String convert(String msg) {
        FlightPathDto flightPathDto = new FlightPathDto();

        flightPathDto.setId(UUID.randomUUID().toString());


        JSONObject jsonObject = JSONUtil.parseObj(msg);

        if (jsonObject.getJSONArray("trace") == null) {
            throw new BusinessException("未知信息");
        }
        Object[] traces = jsonObject.getJSONArray("trace").toArray();

        String icao = (String) jsonObject.getObj("icao");
        flightPathDto.setIcaoCode(icao);

        if (jsonObject.getObj("timestamp") instanceof Long){
            Long timestamp = (Long) jsonObject.getObj("timestamp");
            if (String.valueOf(timestamp).length() == 13){
                flightPathDto.setTimestamp(new Date(timestamp));
            }
        }else {
            BigDecimal timestamp = (BigDecimal) jsonObject.getObj("timestamp");
            if (traces[0] instanceof Integer) {
                Integer trace = (Integer) traces[0];
                Long finalTimeMs = (long) ((timestamp.doubleValue() + trace.doubleValue()) * 1000);
                flightPathDto.setTimestamp(new Date(finalTimeMs));
            } else {
                BigDecimal trace = (BigDecimal) traces[0];
                Long finalTimeMs = (long) ((timestamp.doubleValue() + trace.doubleValue()) * 1000);
                flightPathDto.setTimestamp(new Date(finalTimeMs));
            }
        }


        if (traces[1] instanceof Integer) {
            Integer latitude = (Integer) traces[1];
            flightPathDto.setLatitude(latitude.doubleValue());
        } else {
            BigDecimal latitude = (BigDecimal) traces[1];
            flightPathDto.setLatitude(latitude.doubleValue());
        }

        if (traces[2] instanceof Integer) {
            Integer longitude = (Integer) traces[2];
            flightPathDto.setLongitude(longitude.doubleValue());
        } else {
            BigDecimal longitude = (BigDecimal) traces[2];
            flightPathDto.setLongitude(longitude.doubleValue());
        }

        if (traces[3] instanceof Integer) {
            Integer altitude = (Integer) traces[3];
            flightPathDto.setAltitude(altitude.doubleValue());
        } else if (traces[3] instanceof String) {
            flightPathDto.setAltitude(0.0);
        }

        if (traces[4] instanceof Integer) {
            Integer speed = (Integer) traces[4];
            flightPathDto.setSpeed(speed.doubleValue());
        } else if (traces[4] instanceof JSONNull){
            flightPathDto.setSpeed(0.0);
        }else {
            BigDecimal speed = (BigDecimal) traces[4];
            flightPathDto.setSpeed(speed.doubleValue());
        }

        if (traces[5] instanceof Integer) {
            Integer heading = (Integer) traces[5];
            flightPathDto.setHeading(heading.doubleValue());
        } else {
            BigDecimal heading = (BigDecimal) traces[5];
            flightPathDto.setHeading(heading.doubleValue());
        }

        if (traces[8] instanceof JSONObject) {
            JSONObject sourceType = (JSONObject) traces[8];
            flightPathDto.setSourceType((String) sourceType.get("type"));
        }else{
            flightPathDto.setSourceType("null");
        }

        return JsonUtils.toJson(flightPathDto);
    }
}
